package com.linjiang.design.prototype;

//原型模式
//指原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象
public class PrototypeTest {

    public static void main(String[] args) throws CloneNotSupportedException {
        BaseInfo baseInfo = new BaseInfo("苹果");
        Product product = new Product("part1", "part2", "part3", "part4",baseInfo);

        Product clone = product.clone();
        System.out.println(product);
        System.out.println(clone);

        product.getBaseInfo().setCompanyName("777");
        System.out.println(product);
        System.out.println(clone);
    }
}

class BaseInfo implements Cloneable{
    private String companyName;

    public BaseInfo(String companyName) {
        this.companyName = companyName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }


    @Override
    protected BaseInfo clone() throws CloneNotSupportedException {
        return (BaseInfo) super.clone();
    }

    @Override
    public String toString() {
        return super.hashCode()+"BaseInfo{" +
                "companyName='" + companyName + '\'' +
                '}';
    }
}

class Product implements Cloneable{
    private String part1;
    private String part2;
    private String part3;
    private String part4;

    private BaseInfo baseInfo;

    public Product() {
    }

    @Override
    protected Product clone() throws CloneNotSupportedException {
        Product clone = (Product)super.clone();
        //对类中属性的引用类型进行进一步的拷贝，重新赋值
        BaseInfo cloneBaseInfo = clone.getBaseInfo().clone();
        clone.setBaseInfo(cloneBaseInfo);
        return clone;
    }

    public String getPart1() {
        return part1;
    }

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public String getPart2() {
        return part2;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public String getPart3() {
        return part3;
    }

    public void setPart3(String part3) {
        this.part3 = part3;
    }

    public String getPart4() {
        return part4;
    }

    public void setPart4(String part4) {
        this.part4 = part4;
    }

    public BaseInfo getBaseInfo() {
        return baseInfo;
    }

    public void setBaseInfo(BaseInfo baseInfo) {
        this.baseInfo = baseInfo;
    }

    public Product(String part1, String part2, String part3, String part4, BaseInfo baseInfo) {
        this.part1 = part1;
        this.part2 = part2;
        this.part3 = part3;
        this.part4 = part4;
        this.baseInfo = baseInfo;
    }

    @Override
    public String toString() {
        return super.hashCode()+"Product{" +
                "part1='" + part1 + '\'' +
                ", part2='" + part2 + '\'' +
                ", part3='" + part3 + '\'' +
                ", part4='" + part4 + '\'' +
                ", baseInfo=" + baseInfo +
                '}';
    }
}
